#pragma once
#include <zGraphicsConfig.hpp>
#include <Math/Vector3.hpp>
#include "../Graphics/AABB.hpp"
namespace zzz {
class ZGRAPHICS_CLASS RT_Ray {
public:
	static const float MAX_RAY_RANGE;
	static const float RAY_EPSILON;

	RT_Ray()
  :mint_(RAY_EPSILON), maxt_(MAX_RAY_RANGE) {
	}

	RT_Ray(const Vector3f &ori, const Vector3f &dir, float min = RAY_EPSILON, float max = MAX_RAY_RANGE)
  :ori_(ori), dir_(dir), mint_(min), maxt_(max) {
	}

  bool IntersectP(const AABB3f &aabb, float &hitt0, float &hitt1) const
  {
    float t0 = mint_, t1 = maxt_;
    for (int i = 0; i<3; ++i) {
      //update interval for ith bounding box slab
      float invRayDir = 1.f / dir_[i];
      float tNear = (aabb.Min(i) - ori_[i]) * invRayDir;
      float tFar = (aabb.Max(i) - ori_[i]) * invRayDir;
      //update parametric interval from slab intersection ts
      if (tNear > tFar) Swap(tNear, tFar);
      t0 = tNear > t0 ? tNear : t0;
      t1 = tFar < t1 ? tFar : t1;
      if (t0 > t1) 
        return false;
    }
    hitt0 = t0;
    hitt1 = t1;
    return true;
  }

public:
	Vector3f ori_;
	Vector3f dir_;
	float mint_, maxt_;
};

}
